package com.sks.web.action.house;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Controller;

import com.sks.bean.PageView;
import com.sks.bean.QueryResult;
import com.sks.bean.pojo.Area;
import com.sks.bean.pojo.AuditHistory;
import com.sks.bean.pojo.Config;
import com.sks.bean.pojo.House;
import com.sks.bean.pojo.HouseType;
import com.sks.bean.pojo.Metro;
import com.sks.bean.pojo.MetroStation;
import com.sks.bean.pojo.PayType;
import com.sks.bean.pojo.PropertyType;
import com.sks.bean.pojo.Users;
import com.sks.bean.privilege.Employee;
import com.sks.bean.privilege.SystemPrivilege;
import com.sks.core.SystemConstants;
import com.sks.service.house.AreaService;
import com.sks.service.house.AuditHistoryService;
import com.sks.service.house.BuildingService;
import com.sks.service.house.ConfigService;
import com.sks.service.house.HouseService;
import com.sks.service.house.HouseTypeService;
import com.sks.service.house.MetroService;
import com.sks.service.house.MetroStationService;
import com.sks.service.house.PayTypeService;
import com.sks.service.house.PropertyTypeService;
import com.sks.service.privilege.EmployeeService;
import com.sks.service.privilege.UsersService;
import com.sks.utils.StringUtil;
import com.sks.utils.WebUtil;
import com.sks.web.action.BasicAction;
import com.sks.web.action.privilege.Permission;
import com.sks.web.formbean.house.HouseForm;

@Controller("/cms/house")
public class HouseAction extends BasicAction {
	@Resource(name = "houseServiceBean") private HouseService service;
	@Resource(name = "configServiceBean") private ConfigService configService;
	@Resource(name = "houseTypeServiceBean") private HouseTypeService houseTypeService;
	@Resource(name = "areaServiceBean") private AreaService areaService;
	@Resource(name = "propertyTypeServiceBean") private PropertyTypeService propertyTypeService;
	@Resource(name = "payTypeServiceBean") private PayTypeService payTypeService;
	@Resource(name = "metroStationServiceBean") private MetroStationService metroStationService;
	@Resource(name = "metroServiceBean") private MetroService metroService;
	@Resource(name = "employeeServiceBean") private EmployeeService employeeService;
	@Resource(name = "buildingServiceBean") private BuildingService buildingService;
	@Resource(name = "usersServiceBean") private UsersService userService;
	@Resource(name = "auditHistoryServiceBean") private AuditHistoryService ahService;
	
	protected static String[] baseFields = { "userId", "houseTypeId",
			"stationId", "propertyTypeId", "buildingId", "community",
			"address", "space", "floorAll", "floorAt", "beginDate", "mapInfo",
			"intro", "managePrice", "hits", "isHot", "remark", "houseStatus", "employeeName",
			"auditTime", "publishTime", "finishTime" };

	protected static String[] transFields = { "indate", "linkMan", "mobile",
			"transaStatus", "rentPrice", "rentMode", "rentPayTypeId",
			"rentShareInfo", "houseProperty", "salePayTypeId", "salePrice" };
	
	//protected static String[] auditFields = { "houseStatus", "employeeName",
	//		"createTime", "lastUpdateTime" };
	
	protected static String[] hideFields = {"createTime", "lastUpdateTime"};
	
	protected static String[] onlyBase = mergeArrays(hideFields, transFields/*, auditFields*/);
	protected static String[] onlyTrans = mergeArrays(hideFields, baseFields/*, auditFields*/);
	//protected static String[] onlyAudit = mergeArrays(hideFields, transFields, baseFields);
	
	@Permission(module = SystemPrivilege.MODULE_NAME_HOUSE, privilege = SystemPrivilege.PRIVILEGE_NAME_VIEW)
	public ActionForward list(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		QueryResult<House> qr = null;
		HouseForm formbean = (HouseForm) form;
		PageView<House> pageView = new PageView<House>(12, formbean.getPage());
		List<Object> params = new ArrayList<Object>();
		StringBuffer jpql = new StringBuffer(" o.houseStatus <> ?1 ");
		params.add(House.HOUSE_STATUS_NONE_SUBMIT);
		if ("true".equals(formbean.getQuery())) {// 进行查询操作
			if (!StringUtil.isEmpty(formbean.getTitle())) {
				params.add("%" + formbean.getTitle() + "%");
				jpql.append(" and o.title like ?" + params.size());
			}
			if (!StringUtil.isEmpty(formbean.getHouseStatus())) {
				params.add(formbean.getHouseStatus());
				jpql.append(" and o.houseStatus = ?" + params.size());
			}
			
			if (null != formbean.getTransaStatus()) {
				params.add(formbean.getTransaStatus());
				jpql.append(" and o.transaStatus = ?" + params.size());
			}
			if (null != formbean.getIsHot()) {
				params.add(formbean.getIsHot());
				jpql.append(" and o.isHot = ?" + params.size());
			}
			
			if (null != formbean.getMenuName() && ("salePrice".equals(formbean.getMenuName()) || "rentPrice".equals(formbean.getMenuName()))) {
				if (null != formbean.getMinPrice()) {
					params.add(formbean.getMinPrice().doubleValue());
					jpql.append(" and o." + formbean.getMenuName() + " >= ?" + params.size());
				}
				if (null != formbean.getMaxPrice()) {
					params.add(formbean.getMaxPrice().doubleValue());
					jpql.append(" and o." + formbean.getMenuName() + " <= ?" + params.size());
				}
			}
		}
		LinkedHashMap<String, String> orderby = new LinkedHashMap<String, String>();
		orderby.put("isHot", "desc");
		orderby.put("lastUpdateTime", "desc");
		qr = service.getScrollData(pageView.getFirstResult(), pageView
				.getMaxresult(), jpql.toString(), params.toArray(), orderby);
		pageView.setQueryResult(qr);
		request.setAttribute(PAGEVIEW, pageView);
		this.setReadOnly(request, "list");
		return mapping.findForward(LIST);
	}
	
	@Permission(module = SystemPrivilege.MODULE_NAME_HOUSE, privilege = SystemPrivilege.PRIVILEGE_NAME_UPDATE)
	public ActionForward addUI(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		this.saveToken(request);
		HouseForm formbean = (HouseForm) form;
		getBaseData(request, formbean);
		formbean.setMethod(ADD);
		return mapping.findForward(EDIT);
	}
	
	public void beforeadd(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		ActionMessages errors = new ActionErrors();
		HouseForm formbean = (HouseForm) form;
		
		if (StringUtil.isEmpty(formbean.getTitle())) {
			errors.add("title", new ActionMessage("errors.required", getMessage("info.house.field.title")));
		}
		
		List params = new ArrayList();
		params.add(formbean.getTitle());
		StringBuffer jpql = new StringBuffer("o.title = ?" + params.size());
		if (EDIT.equals(formbean.getMethod())) {
			params.add(formbean.getHouseId());
			jpql.append(" and o.houseId <> ?" + params.size());
		}
		QueryResult<House> m = service.getScrollData(-1, -1, jpql.toString(),
				params.toArray());
		
		if (null != m && m.getResultlist().size() > 0) {
			// 提示信息
			errors.add("title", new ActionMessage("errors.repeat", getMessage("info.house.field.title")));
			getBaseData(request, formbean);
		}
		saveErrors(request, errors);
	}
	
	@Permission(module = SystemPrivilege.MODULE_NAME_HOUSE, privilege = SystemPrivilege.PRIVILEGE_NAME_UPDATE)
	public ActionForward add(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		HouseForm formbean = (HouseForm) form;
		formbean.setIsHot(true);
		House house = new House();
		copyProperties(formbean, house);
		house.setHouseId(null);
		house.setCreateTime(new Date());
		house.setLastUpdateTime(new Date());
		house.setArea(null == formbean.getAreaId() ? null : areaService.find(formbean.getAreaId()));
		house.setHouseStatus(House.HOUSE_STATUS_NONE_AUDIT);
		house.setTransaStatus(0);
		//house.setEmployee(employeeService.find(WebUtil.getEmployee(request).getUsername()));
		setObjectInHouse(house, formbean, request);
		service.save(house);
		formbean.setHouseId(house.getHouseId());
		formbean.setType("Base");
		return editUI(mapping, formbean, request, response);
	}
	
	@Permission(module = SystemPrivilege.MODULE_NAME_HOUSE, privilege = SystemPrivilege.PRIVILEGE_NAME_VIEW)
	public ActionForward editUI(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		this.saveToken(request);
		HouseForm formbean = (HouseForm) form;
		
		Boolean isBase = "Base".equals(formbean.getType());
		House house = service.find(formbean.getHouseId());
		
		copyProperties(house, formbean, formbean.getType());
		
		if (isBase) {
			getBaseData(request, formbean);
			formbean.setBuildingName(null != house.getBuilding() ? house.getBuilding().getName() : null);
			request.setAttribute("selectedConfigs", house.getConfigs());
		} else if ("Trans".equals(formbean.getType())) {
			getTransData(request);
		} /*else if ("Audit".equals(formbean.getType())) {
			formbean.setAuditTime(house.getAuditTime());
			formbean.setPublishTime(house.getPublishTime());
		}*/
		formbean.setMethod(EDIT);
		String returnForward = EDIT + (isBase ? "" : formbean.getType());
		
		if (House.HOUSE_STATUS_NONE_AUDIT.equals(house.getHouseStatus())) {//只有在未审核的状态下才能修改房源
			this.setReadOnly(request, "editUI");
		} else {
			request.setAttribute(SystemConstants.SYS_IS_READ_ONLY, true);
		}
		
		//检查是否有房源审核权限
		request.setAttribute(SystemConstants.SYS_CAN_AUDIT,
				WebUtil.hasPermission(request, SystemPrivilege.MODULE_NAME_HOUSE, SystemPrivilege.PRIVILEGE_NAME_AUDIT));
		return mapping.findForward(returnForward);
	}
	
	public void beforeedit(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		this.beforeadd(mapping, form, request, response);
	}
	
	@Permission(module = SystemPrivilege.MODULE_NAME_HOUSE, privilege = SystemPrivilege.PRIVILEGE_NAME_UPDATE)
	public ActionForward edit(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		HouseForm formbean = (HouseForm) form;
		House house = service.find(formbean.getHouseId());
		
		if (!House.HOUSE_STATUS_NONE_AUDIT.equals(house.getHouseStatus())) {
			request.setAttribute(MESSAGE, getMessage("error.house.doNotEdit"));
			request.setAttribute("urladdress", "/cms/house.do?method=editUI&houseId="
					+ formbean.getHouseId() + "&type=" + formbean.getType());
			return mapping.findForward(MESSAGE);
		}
		
		copyProperties(formbean, house, formbean.getType());
		if ("Base".equals(formbean.getType())) {
			setObjectInHouse(house, formbean, request);
			
		} else if ("Trans".equals(formbean.getType())) {
			house.setRentPayType(payTypeService.find(house.getRentPayTypeId(), false));
			house.setSalePayType(payTypeService.find(house.getSalePayTypeId(), false));
		}
		
		service.update(house);
		return editUI(mapping, formbean, request, response);
	}
	
	private void setObjectInHouse(House house, HouseForm formbean, HttpServletRequest request) {
		house.setBuilding(buildingService.find(formbean.getBuildingId(), false));
		house.setUsers(userService.find(formbean.getUserId(), false));
		house.setArea(areaService.find(formbean.getAreaId(), false));
		house.setHouseType(houseTypeService.find(formbean.getHouseTypeId(), false));
		house.setMetroStation(metroStationService.find(formbean.getMetroStationId(), false));
		house.setPropertyType(propertyTypeService.find(formbean.getPropertyTypeId(), false));
		Employee emp = employeeService.find(formbean.getEmployeeName(), false);
		if (null == emp) {
			emp = employeeService.find(WebUtil.getEmployee(request).getUsername());
		}
		house.setEmployee(emp);
		Set<Config> cons = house.getConfigs();
		if (null == cons) {
			cons = new HashSet<Config>(0);
		} else {
			cons.clear();
		}
		if (null != formbean.getConfigIds()) {
			for (Integer configId : formbean.getConfigIds()) {
				Config c = configService.find(configId);
				cons.add(c);
			}
		}
		house.setConfigs(cons);
	}

	private void getTransData(HttpServletRequest request) {
		List<PayType> rpts = payTypeService.getRentPayType();
		List<PayType> spts = payTypeService.getSalePayType();
		request.setAttribute("rpts", rpts);
		request.setAttribute("spts", spts);
	}
	
	private void getBaseData(HttpServletRequest request, HouseForm formbean) {
		List<Config> cs = configService.getScrollData().getResultlist();
		List<HouseType> hts = houseTypeService.getScrollData().getResultlist();
		List<MetroStation> mss = new ArrayList<MetroStation>(0);
		List<Metro> ms = metroService.getScrollData().getResultlist();
		if (null != formbean.getMetroStationId()) {
			MetroStation stasion = metroStationService.find(formbean.getMetroStationId());
			if (null != stasion.getMetroByMetroId()) {
				mss.addAll(stasion.getMetroByMetroId().getMetroStationsForMetroId());
				formbean.setMetroId(stasion.getMetroByMetroId().getMetroId());
			} else if (null != stasion.getMetroByMetroId1()) {
				mss.addAll(stasion.getMetroByMetroId1().getMetroStationsForMetroId());
				formbean.setMetroId(stasion.getMetroByMetroId1().getMetroId());
			}
		} else {
			formbean.setMetroId(null);
		}
		
		Users user = userService.find(formbean.getUserId(), false);
		if (null != user) {
			formbean.setUserName(user.getLoginName());
		}
		
		List<Area> tops = areaService.findAreas(true, null);
		List<Area> lows = new ArrayList<Area>(0);
		Integer areaId = formbean.getAreaId();
		if (null != areaId) {
			Area area = areaService.find(areaId);
			lows.addAll(area.getParentArea().getAreas());
			formbean.setTopAreaId(area.getParentArea().getAreaId());
		} else {
			formbean.setTopAreaId(null);
		}
		List<PropertyType> ppts = propertyTypeService.getScrollData().getResultlist();
		
		request.setAttribute("cs", cs);
		request.setAttribute("hts", hts);
		request.setAttribute("mss", mss);
		request.setAttribute("ms", ms);
		request.setAttribute("ppts", ppts);
		request.setAttribute("tops", tops);
		request.setAttribute("lows", lows);
	}
	
	protected static void copyProperties(Object source, Object target, String type) {
		String[] ignorePros = null;
		if ("Base".equals(type)) {
			ignorePros = onlyBase;
		} else if ("Trans".equals(type)) {
			ignorePros = onlyTrans;
		}
		BeanUtils.copyProperties(source, target, ignorePros);
	}
	
	private static String[] mergeArrays(String[] ... strings) {
		Integer newLen = 0;
		for (String[] strs : strings) {
			newLen += strs.length;
		}
		String[] newArray = new String[newLen];
		Integer temp = 0;
		for (int i = 0; i < strings.length; i++) {
			String[] strs = strings[i];
			System.arraycopy(strs, 0, newArray, temp, strs.length);
			temp += strs.length;
		}
		return newArray;
	}
	
	@Permission(module = SystemPrivilege.MODULE_NAME_HOUSE, privilege = SystemPrivilege.PRIVILEGE_NAME_AUDIT)
	public ActionForward changeStatus(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		HouseForm formbean = (HouseForm) form;
		formbean.setType("Base");
		House house = service.find(formbean.getHouseId());
		if (null != house) {
			
			String oldStatus = house.getHouseStatus();
			String newStatus = formbean.getHouseStatus();
			Date date = new Date();
			
			if (House.HOUSE_STATUS_NONE_AUDIT.equals(oldStatus)) {//未审核
				if (House.HOUSE_STATUS_AUDITED.equals(newStatus)) {//已审核
					house.setHouseStatus(House.HOUSE_STATUS_AUDITED);
					house.setAuditTime(date);
				}
			} else if (House.HOUSE_STATUS_AUDITED.equals(oldStatus)) {//已审核
				if (House.HOUSE_STATUS_NONE_AUDIT.equals(newStatus)) {//撤销审核
					house.setHouseStatus(House.HOUSE_STATUS_NONE_AUDIT);
					house.setAuditTime(null);
				} else if (House.HOUSE_STATUS_PUBLISHED.equals(newStatus)) {//审核->已发布
					house.setHouseStatus(House.HOUSE_STATUS_PUBLISHED);
					house.setPublishTime(date);
				}
			} else if (House.HOUSE_STATUS_PUBLISHED.equals(oldStatus)) {//已发布
				if (House.HOUSE_STATUS_FINISHED.equals(newStatus)) {//完成
					house.setHouseStatus(House.HOUSE_STATUS_FINISHED);
					house.setFinishTime(date);
				} else if (House.HOUSE_STATUS_INVALIDATE.equals(newStatus)) {//失效
					house.setHouseStatus(House.HOUSE_STATUS_INVALIDATE);
				} else if (House.HOUSE_STATUS_AUDITED.equals(newStatus)) {//撤销发布返回已审核状态
					house.setHouseStatus(House.HOUSE_STATUS_AUDITED);
					house.setPublishTime(null);
				}
			} else if (House.HOUSE_STATUS_FINISHED.equals(oldStatus) ||
					House.HOUSE_STATUS_INVALIDATE.equals(oldStatus)) {//已完成交易或失效状态
				if (House.HOUSE_STATUS_NONE_AUDIT.equals(newStatus)) {//撤销为未审核状态
					house.setHouseStatus(House.HOUSE_STATUS_NONE_AUDIT);
					house.setFinishTime(null);
				}
			}
			service.update(house);
			
			Employee emp = WebUtil.getEmployee(request);
			emp = employeeService.find(emp.getUsername());
			AuditHistory ah = new AuditHistory(emp, AuditHistory.OBJ_TYPE_HOUSE, house.getHouseId(), date, oldStatus, newStatus);
			ahService.save(ah);
		}
		return editUI(mapping, form, request, response);
	}
	
	@Permission(module = SystemPrivilege.MODULE_NAME_HOUSE, privilege = SystemPrivilege.PRIVILEGE_NAME_UPDATE)
	public ActionForward saveEmployee(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		try {
			HouseForm formbean = (HouseForm) form;
			House house = service.find(formbean.getHouseId());
			Employee emp = employeeService.find(formbean.getEmployeeName());
			if (null == emp) {
				emp = employeeService.find(WebUtil.getEmployee(request).getUsername());
			}
			house.setEmployee(emp);
			service.update(house);
			response.getWriter().print("{success:true}");
		} catch (Exception e) {
			e.printStackTrace();
			response.getWriter().print("{success:false}");
		}
		return null;
	}
	
	@Permission(module = SystemPrivilege.MODULE_NAME_HOUSE, privilege = SystemPrivilege.PRIVILEGE_NAME_UPDATE)
	public ActionForward delete(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		HouseForm formbean = (HouseForm) form;
		House house = service.find(formbean.getHouseId());
		String status = null;
		String msg = null;
		if (null == house) {
			msg = getMessage("errors.nofound", getMessage("info.house.name"));
		} else if(!House.HOUSE_STATUS_NONE_AUDIT.equals(house.getHouseStatus())) {
			msg = getMessage("error.house.doNotDelete");
		} else {
			status = house.getHouseStatus();
			service.delete(house.getHouseId());
			msg = getMessage("info.delete.success", getMessage("info.house.name"));
		}
		
		request.setAttribute(MESSAGE, msg);
		request.setAttribute("urladdress", "/cms/house.do?method=list&query=true&houseStatus=" + status);
		return mapping.findForward(MESSAGE);
	}
	
	//ajax专用，不用permission注解
	public ActionForward setHot(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		boolean success = false;
		String msg = "";
		if (!WebUtil.hasPermission(WebUtil.getEmployee(request), "house", "update")) {
			success = false;
			msg = "没有编辑房源的权限";
		} else {
			HouseForm formbean = (HouseForm) form;
			House house = service.find(formbean.getHouseId(), false);
			if (null == house) {
				success = false;
				msg = getMessage("errors.nofound", getMessage("info.house.name"));
			} else {
				try {
					house.setIsHot(formbean.getIsHot());
					service.update(house);
					success = true;
				} catch (Exception e) {
					success = false;
					msg = getMessage("error.house.setHot");
				}
			}
		}
		response.getWriter().print("{success:"+success+",msg:'"+msg+"'}");
		return null;
	}
}
